#include <iostream>
#include <fstream>
#include <list>
#include <sstream>
#include <arm_neon.h>
#include <sys/time.h>
#include <bitset>

using namespace::std;

timeval tv_begin;
timeval tv_end;

bitset<9000000> x[1756];
bitset<9000> y[1756];

int main()
{
    ofstream outfile;
    outfile.open("output.txt", ios::out);
    ifstream index("ExpIndex",ios::binary);
    int t_count;
    int s_count = 0;
    while(index.read((char*) &t_count, 4))
    {
        int tmp;
        for(int i = 0;i < t_count;i++)
        {
            index.read((char*) &tmp, 4);
            if(tmp >= 0 && tmp < 9000000)
            {
                x[s_count][tmp] = 1;
            }
        }
        s_count++;
    }
    for(int o = 0;o < 1756;o++)
    {
        for(int i = 0;i < 9000000;i+=1000)
        {
            int flag = 0;
            for(int j = i;j < i + 1000;j++)
            {
                if(x[o][j] == 1)
                {
                    flag = 1;
                    break;
                }
            }
            if(flag == 1)
            {
                y[o][i/1000] = 1;
            }
        }
    }
    index.close();
    ifstream query("ExpQuery",ios::in);
    string str;
    while(getline(query,str))
    {
        stringstream s(str);
        int z[6];
        int n = 0;
        string ch;
        while(s >> ch)
        {
            int t = 0;
            for(int i = 0;i < ch.length();i++)
            {
                t = t*10 + ((int)ch[i] - (int)'0');
            }
            z[n] = t;
            n++;
        }
        gettimeofday(&tv_begin, 0);
        bitset<9000000> tp(0);
        for(int i = 0;i < 9000;i++)
        {
            if(y[z[0]][i] == 1)
            {
                bitset<1000> and = and_neon(z,1000,n,i*1000);
                for(int j = 0;j < 1000;j++)
                {
                    if(and[j] == 1)
                    {
                        tp[j + i*1000] = 1;
                    }
                }
            }
        }
        gettimeofday(&tv_end, 0);
        outfile<<((double)tv_end.tv_sec - (double)tv_begin.tv_sec)*10.0 + ((double)tv_end.tv_usec - (double)tv_begin.tv_usec)/100000.0<<"ms"<<endl;
    }
    query.close();
    system("pause");
    return 0;
}

int and_neon(int* z,int p,int n,int q)
{
    int32x4_t and4 = vmovq_n_f32(1);
    for(int i = 0;i < p;i += 128)
    {
        for(o = 0;o < n;o++)
        {
            int32x4_t tmp = vldlq_f32(x[z[o]]+ i + q);
            and4 = uint32x4_t(and4,tmp);
        }
    }
    if(i - 128 < n)
    {
        int32x4_t tmp = vldlq_f32(x[p] + p + q);
        and4 = uint32x4_t(and4,tmp);
    }
    int32x2_t andl2=vget_low_f32(and4);
    int32x2_t andh2=vget_high_f32(and4);
    andl2=vpadd_f32(andl2,andh2);
    int32_t sum=vpadds_f32(suml2);
    return (int)sum;
}
